package scatter.wwd.rest.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import scatter.common.LoginUser;
import scatter.common.rest.controller.BaseAddUpdateQueryFormController;
import scatter.common.rest.exception.BusinessDataNotFoundException;
import scatter.common.rest.exception.BusinessException;
import scatter.common.rest.security.LoginUserTool;
import scatter.dict.rest.service.IDictService;
import scatter.wwd.pojo.form.*;
import scatter.wwd.pojo.po.UserInfo;
import scatter.wwd.pojo.vo.UserEnjoyStatusVo;
import scatter.wwd.pojo.vo.UserInfoDetailVo;
import scatter.wwd.pojo.vo.UserInfoSelfVo;
import scatter.wwd.pojo.vo.UserInfoVo;
import scatter.wwd.rest.WwdConfiguration;
import scatter.wwd.rest.mapstruct.UserInfoMapStruct;
import scatter.wwd.rest.service.IUserEnjoyService;
import scatter.wwd.rest.service.IUserInfoService;
import scatter.wwd.rest.service.IUserVisitService;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

/**
 * <p>
 * 用户信息表 前端控制器
 * </p>
 *
 * @author yw
 * @since 2020-12-08
 */
@Slf4j
@RestController
@RequestMapping(WwdConfiguration.CONTROLLER_BASE_PATH + "/user-info")
@Api(tags = "用户信息")
public class UserInfoController extends BaseAddUpdateQueryFormController<UserInfo, UserInfoVo, UserInfoAddForm, UserInfoUpdateForm, UserInfoPageQueryForm> {

    @Autowired
    private IUserInfoService iUserInfoService;

    @Qualifier("commonDbTaskExecutor")
    @Autowired
    ExecutorService commonDbTaskExecutor;

    @Autowired
    private IUserEnjoyService iUserEnjoyService;


    @Override
	@ApiOperation("添加用户信息")
    @PreAuthorize("hasAuthority('UserInfo:add')")
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public UserInfoVo add(@RequestBody @Valid UserInfoAddForm addForm) {
        return super.add(addForm);
    }

    @Override
	@ApiOperation("根据ID查询用户信息")
    @PreAuthorize("hasAuthority('UserInfo:queryById')")
    @GetMapping("/{id}")
    @ResponseStatus(HttpStatus.OK)
    public UserInfoVo queryById(@PathVariable String id) {
        return super.queryById(id);
    }

    @ApiOperation("根据USERID查询用户信息")
    @PreAuthorize("hasAuthority('UserInfo:queryByUserId')")
    @GetMapping("/userId/{userId}")
    @ResponseStatus(HttpStatus.OK)
    public UserInfoVo queryByUserId(@PathVariable String userId) {
        UserInfo byUserId = iUserInfoService.getByUserId(userId);
        if (byUserId == null) {
            throw new BusinessDataNotFoundException(true);
        }
        UserInfoVo userInfoVo = UserInfoMapStruct.INSTANCE.poToVo(byUserId);
        return userInfoVo;
    }

    @Override
	@ApiOperation("根据ID删除用户信息")
    @PreAuthorize("hasAuthority('UserInfo:deleteById')")
    @DeleteMapping("/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public boolean deleteById(@PathVariable String id) {
        return super.deleteById(id);
    }

    @Override
	@ApiOperation("根据ID更新用户信息")
    @PreAuthorize("hasAuthority('UserInfo:update')")
    @PutMapping
    @ResponseStatus(HttpStatus.CREATED)
    public UserInfoVo update(@RequestBody @Valid UserInfoUpdateForm updateForm) {
        return super.update(updateForm);
    }

    @Override
	@ApiOperation("不分页查询用户信息")
    @PreAuthorize("hasAuthority('UserInfo:getList')")
    @GetMapping("/getList")
    @ResponseStatus(HttpStatus.OK)
    public List<UserInfoVo> getList(UserInfoPageQueryForm listPageForm) {
        return super.getList(listPageForm);
    }

    @Override
	@ApiOperation("分页查询用户信息")
    @PreAuthorize("hasAuthority('UserInfo:getPage')")
    @GetMapping("/getPage")
    @ResponseStatus(HttpStatus.OK)
    public IPage<UserInfoVo> getPage(UserInfoPageQueryForm listPageForm) {
        return super.getPage(listPageForm);
    }




    @ApiOperation("更新自己用户信息")
    @PreAuthorize("hasAuthority('user')")
    @PutMapping("/updateSelfInfo")
    @ResponseStatus(HttpStatus.CREATED)
    public UserInfoVo update(@RequestBody @Valid UserInfoUpdateForm1 updateForm,@ApiIgnore LoginUser loginUser) {
        updateForm.setUserId(loginUser.getId());
        UserInfo byUserId = iUserInfoService.getByUserId(loginUser.getId());

        UserInfo userInfo = UserInfoMapStruct.INSTANCE.userInfoUpdateForm1ToPo(updateForm);
        userInfo.setId(byUserId.getId());
        iUserInfoService.save(userInfo);
        return getVo(iUserInfoService.getById(userInfo.getId()));

    }



    @ApiOperation("分页查询同城用户信息")
    @PreAuthorize("hasAuthority('appclient')")
    @GetMapping("/getPageBySameCity")
    @ResponseStatus(HttpStatus.OK)
    public IPage<UserInfoVo> getPageBySameCity(UserInfoPageSameCityQueryForm queryForm, @ApiIgnore LoginUser loginUser) {
        List<UserInfoVo> userInfoVos = null;
        queryForm.setUserId(loginUser.getId());
        IPage<UserInfo> pageBySameCity = iUserInfoService.getPageBySameCity(queryForm);

        IPage<UserInfoVo> userInfoVoIPage = pagePoToVo(pageBySameCity);
        return userInfoVoIPage;
    }


    /**
     * 首页用户推荐,邂逅
     *
     * @param queryForm 用户的性别
     * @return
     */
    @ApiOperation("首页用户推荐")
    @GetMapping("/recommend")
    @ResponseStatus(HttpStatus.OK)
    public List<UserInfoVo> recommend(UserInfoPageQueryForm queryForm, HttpServletRequest request) {

        LoginUser loginUser = LoginUserTool.getLoginUser();
        List<UserInfoVo> userInfoVos = null;
        // 缓存中尝试取
        Object attribute = request.getSession().getAttribute("userinfo-recommend");
        if (attribute != null) {
            // userInfoVos =  (List<UserInfoVo>) attribute;
        }
        // 缓存中没有尝试推荐数据
        if (userInfoVos == null) {
            userInfoVos = super.posToVos(iUserInfoService.recommend(loginUser, queryForm));
            if(isEmpty(userInfoVos)){
                //搜索无数据重置查询条件
                userInfoVos = super.posToVos(iUserInfoService.recommend(loginUser, new UserInfoPageQueryForm()));
            }
            // 只缓存静态数据
            request.getSession().setAttribute("userinfo-recommend", userInfoVos);
        }
        return userInfoVos;
    }

    /**
     * 设置双方喜欢状态
     * @param userInfoVos
     * @param loginUser
     */
    private void setUserEnjoyStatus(List<UserInfoDetailVo> userInfoVos,LoginUser loginUser){

        if (!isEmpty(userInfoVos)) {
            // 添加有意思状态
            if (loginUser != null) {
                List<Future<UserEnjoyStatusVo>> futureTasks = new ArrayList<>(userInfoVos.size());
                for (UserInfoVo userInfoVo : userInfoVos) {
                    futureTasks.add(commonDbTaskExecutor.submit(()->iUserEnjoyService.getUserEnjoyStatus(loginUser.getId(),userInfoVo.getUserId())));
                }
                for (int i = 0; i < userInfoVos.size(); i++) {
                    try {
                        userInfoVos.get(i).setUserEnjoyStatus(futureTasks.get(i).get());
                    } catch (InterruptedException e) {
                        log.error("commonDbTaskExecutor 异步线程池中断异常",e);
                    } catch (ExecutionException e) {
                        log.error("commonDbTaskExecutor 异步线程池执行异常",e);
                    }
                }
            }

        }
    }

    /**
     * @param userId
     * @return
     */
    @ApiOperation("根据用户ID查询用户信息详情")
    @GetMapping("/{userId}/detail")
    @ResponseStatus(HttpStatus.OK)
    public UserInfoDetailVo queryDetailByUserId(@PathVariable String userId,@ApiIgnore LoginUser loginUser) {
        UserInfo byUserId = iUserInfoService.getByUserId(userId);
        if (byUserId == null) {
            throw new BusinessDataNotFoundException(true);
        }
        UserInfoDetailVo userInfoDetailVo = UserInfoMapStruct.INSTANCE.mapDetail(byUserId);
        // 设置当前登录用户对该用户的有意思状态
        if (loginUser != null) {
            userInfoDetailVo.setUserEnjoyStatus(iUserEnjoyService.getUserEnjoyStatus(loginUser.getId(),userId));
        }

        return userInfoDetailVo;
    }

    @ApiOperation(value = "获取用户自己的微信号")
    @GetMapping("/wxNumber")
    @PreAuthorize("hasAuthority('user')")
    @ResponseStatus(HttpStatus.OK)
    public String wxNumber(@ApiIgnore LoginUser loginUser) {
        UserInfo byUserId = iUserInfoService.getByUserId(loginUser.getId());
        if (isStrEmpty(byUserId.getWechatNumber())) {
            throw new BusinessException("未设置微信号",true);
        }

        return  byUserId.getWechatNumber();

    }


    @ApiOperation(value = "获取用户微信号",notes = "仅限双方有意思后获取使用")
    @GetMapping("/enjoyed/wxNumber/{userId}")
    @PreAuthorize("hasAuthority('user')")
    @ResponseStatus(HttpStatus.OK)
    public String queryWxNumbrByUserId(@PathVariable String userId, @ApiIgnore LoginUser loginUser) {
        UserEnjoyStatusVo userEnjoyStatus = iUserEnjoyService.getUserEnjoyStatus(loginUser.getId(), userId);
        if (userEnjoyStatus.getIsEnjoy() && userEnjoyStatus.getIsEnjoyed()) {
            UserInfo byId = getIBaseService().getById(userId);
            if (isStrEmpty(byId.getWechatNumber())) {
                throw new BusinessException("该用户未设置微信号",true);
            }
            return byId.getWechatNumber();
        }

        throw new BusinessException("双方互有意思后才可以获取哦",true);

    }
    @ApiOperation("获取用户自己信息")
    @PreAuthorize("hasAuthority('user')")
    @GetMapping("/userInfoSelf")
    @ResponseStatus(HttpStatus.OK)
    public UserInfoSelfVo userInfoSelf(@ApiIgnore LoginUser loginUser) {
        UserInfo byUserId = iUserInfoService.getByUserId(loginUser.getId());
        UserInfoSelfVo userInfoSelfVo = UserInfoMapStruct.INSTANCE.poToUserInfoSelfVo(byUserId);
        return userInfoSelfVo;
    }

}
